<template>
  <div class="transfer-wrapper">
    <div class="transfer-tree">
      <el-tree
        ref="treeRef"
        :data="afferentData"
        show-checkbox
        node-key="id"
        :props="defaultProps"
        @current-change="currentChange"
        @check="onElTreeCheck"
        >
      </el-tree>
    </div>
    <div class="transfer-connect">
      <el-icon ><arrow-right  /></el-icon>
    </div>
    <div class="show-transfer-data">
      <el-tree
        :data="resultData"
        node-key="id"
        :props="defaultProps">
      </el-tree>
    </div>
  </div>
</template>

<script lang="ts">
import { ArrowRight } from '@element-plus/icons-vue'
import { defineComponent, ref } from '@vue/runtime-core';

type TreeData = {
  id: number,
  label: string,
  checked?: boolean,
  indeterminate?: boolean,
  children: TreeData[]
}
export default defineComponent({
  components: {
		ArrowRight
	},
  name:'TransferTree',
  setup() {
    const treeRef = ref<any>(null)
    const afferentData = <TreeData[]>[
      {
        id: 1,
        label: '一级 1',
        children: [
          {
            id: 4,
            label: '二级 1-1',
            children: [
              {
                id: 6,
                label: '三级 3-1',
                children: []
              }
            ]
          },
          {
            id: 5,
            label: '二级 1-3',
            children: []
          }
        ]
      },
      {
        id: 2,
        label: '一级 2',
        children: []
      }
    ]
    let resultData = ref(<TreeData[]>[]);
    const defaultProps = {
          children: 'children',
          label: 'label'
        }
    const currentChange = (data: TreeData, node: any) => {
      console.log(data, node)
      console.log(treeRef.value.getCheckedKeys())
    }


    const setTreeDataItemChildrenChecked = (treeData: TreeData) => {
      if (treeData.children && treeData.children.length) { 
        treeData.children.forEach((item) => {
          item.checked = true;

          setTreeDataItemChildrenChecked(item);
        });
      }
    };

    const setTreeDataItemChecked = (treeData: TreeData[], checkedItems: TreeData[]) => {
      treeData.forEach((item) => {
        for (let i = 0; i < checkedItems.length; i++) {
          if (item.id === checkedItems[i].id) {
            item.checked = true;
            setTreeDataItemChildrenChecked(item);
          } else {
            setTreeDataItemChecked(item.children, checkedItems);
          }
        }
      });

      return treeData;
    };

    const setTreeDataParentIndeterminate = (treeData: TreeData[]) => {
      treeData.forEach((item) => {
        let flag = false;

        item.children.forEach((item2) => {
          if (item2.checked) {
            flag = true;
          }
        });

        item.indeterminate = flag;

        setTreeDataParentIndeterminate(item.children);
      });
    };

    const filterUnCheckedData = (treeData: TreeData[]) => {
      for (let i = 0; i < treeData.length; i++) {
        if (!treeData[i].checked && !treeData[i].indeterminate) {
          treeData.splice(i, 1);
          i--;
        } else {
          filterUnCheckedData(treeData[i].children);
        }
      }
    };

    const onElTreeCheck = (data: TreeData, checkState: any) => {
      // 在原数据中设置已选中flag，始终传入拷贝的原数据，避免改动原数据
      const result = setTreeDataItemChecked(JSON.parse(JSON.stringify(afferentData)), checkState.checkedNodes);
      setTreeDataParentIndeterminate(result);

      // 过滤掉checked为false和indeterminate为false的值
      filterUnCheckedData(result);

      resultData.value = result;
    }

    return {
      treeRef,
      afferentData,
      resultData,
      defaultProps,
      currentChange,
      onElTreeCheck,
    }
  }
})
</script>

<style lang="scss" scoped>
.transfer-wrapper {
  display: flex;
  align-items: center;

  .transfer-tree {
    width: 200px;
  }

  .transfer-connect {
    & > i {
      font-size: 40px;
      color: $regularText;
    }
  }

  .show-transfer-data {
    width: 200px;
  }
}
</style>